{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\ProgramData\\Anaconda3\\lib\\site-packages\\lightfm\\_lightfm_fast.py:9: UserWarning: LightFM was compiled without OpenMP support. Only a single thread will be used.\n",
      "  warnings.warn('LightFM was compiled without OpenMP support. '\n",
      "b'Skipping line 6452: expected 8 fields, saw 9\\nSkipping line 43667: expected 8 fields, saw 10\\nSkipping line 51751: expected 8 fields, saw 9\\n'\n",
      "b'Skipping line 92038: expected 8 fields, saw 9\\nSkipping line 104319: expected 8 fields, saw 9\\nSkipping line 121768: expected 8 fields, saw 9\\n'\n",
      "b'Skipping line 144058: expected 8 fields, saw 9\\nSkipping line 150789: expected 8 fields, saw 9\\nSkipping line 157128: expected 8 fields, saw 9\\nSkipping line 180189: expected 8 fields, saw 9\\nSkipping line 185738: expected 8 fields, saw 9\\n'\n",
      "b'Skipping line 209388: expected 8 fields, saw 9\\nSkipping line 220626: expected 8 fields, saw 9\\nSkipping line 227933: expected 8 fields, saw 11\\nSkipping line 228957: expected 8 fields, saw 10\\nSkipping line 245933: expected 8 fields, saw 9\\nSkipping line 251296: expected 8 fields, saw 9\\nSkipping line 259941: expected 8 fields, saw 9\\nSkipping line 261529: expected 8 fields, saw 9\\n'\n",
      "C:\\ProgramData\\Anaconda3\\lib\\site-packages\\IPython\\core\\interactiveshell.py:2785: DtypeWarning: Columns (3) have mixed types. Specify dtype option on import or set low_memory=False.\n",
      "  interactivity=interactivity, compiler=compiler, result=result)\n"
     ]
    }
   ],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from datetime import datetime, timedelta\n",
    "from sklearn import preprocessing\n",
    "from lightfm import LightFM\n",
    "from scipy.sparse import csr_matrix \n",
    "from scipy.sparse import coo_matrix \n",
    "from sklearn.metrics import roc_auc_score\n",
    "import time\n",
    "from lightfm.evaluation import auc_score\n",
    "import pickle\n",
    "import re\n",
    "import seaborn as sns\n",
    "\n",
    "\n",
    "books = pd.read_csv('BX-Books.csv', sep=';', error_bad_lines=False, encoding=\"latin-1\")\n",
    "books.columns = ['ISBN', 'bookTitle', 'bookAuthor', 'yearOfPublication', 'publisher', 'imageUrlS', 'imageUrlM', 'imageUrlL']\n",
    "users = pd.read_csv('BX-Users.csv', sep=';', error_bad_lines=False, encoding=\"latin-1\")\n",
    "users.columns = ['userID', 'Location', 'Age']\n",
    "ratings = pd.read_csv('BX-Book-Ratings.csv', sep=';', error_bad_lines=False, encoding=\"latin-1\")\n",
    "ratings.columns = ['userID', 'ISBN', 'bookRating']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1149780, 3)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ratings.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>userID</th>\n",
       "      <th>ISBN</th>\n",
       "      <th>bookRating</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>276725</td>\n",
       "      <td>034545104X</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>276726</td>\n",
       "      <td>0155061224</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>276727</td>\n",
       "      <td>0446520802</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>276729</td>\n",
       "      <td>052165615X</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>276729</td>\n",
       "      <td>0521795028</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   userID        ISBN  bookRating\n",
       "0  276725  034545104X           0\n",
       "1  276726  0155061224           5\n",
       "2  276727  0446520802           0\n",
       "3  276729  052165615X           3\n",
       "4  276729  0521795028           6"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ratings.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "books.drop(['imageUrlS', 'imageUrlM', 'imageUrlL'],axis=1,inplace=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "books.loc[books.ISBN == '0789466953','yearOfPublication'] = 2000\n",
    "books.loc[books.ISBN == '0789466953','bookAuthor'] = \"James Buckley\"\n",
    "books.loc[books.ISBN == '0789466953','publisher'] = \"DK Publishing Inc\"\n",
    "books.loc[books.ISBN == '0789466953','bookTitle'] = \"DK Readers: Creating the X-Men, How Comic Books Come to Life (Level 4: Proficient Readers)\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "books.loc[books.ISBN == '078946697X','yearOfPublication'] = 2000\n",
    "books.loc[books.ISBN == '078946697X','bookAuthor'] = \"Michael Teitelbaum\"\n",
    "books.loc[books.ISBN == '078946697X','publisher'] = \"DK Publishing Inc\"\n",
    "books.loc[books.ISBN == '078946697X','bookTitle'] = \"DK Readers: Creating the X-Men, How It All Began (Level 4: Proficient Readers)\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ISBN</th>\n",
       "      <th>bookTitle</th>\n",
       "      <th>bookAuthor</th>\n",
       "      <th>yearOfPublication</th>\n",
       "      <th>publisher</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>209538</th>\n",
       "      <td>078946697X</td>\n",
       "      <td>DK Readers: Creating the X-Men, How It All Beg...</td>\n",
       "      <td>Michael Teitelbaum</td>\n",
       "      <td>2000</td>\n",
       "      <td>DK Publishing Inc</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>221678</th>\n",
       "      <td>0789466953</td>\n",
       "      <td>DK Readers: Creating the X-Men, How Comic Book...</td>\n",
       "      <td>James Buckley</td>\n",
       "      <td>2000</td>\n",
       "      <td>DK Publishing Inc</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "              ISBN                                          bookTitle  \\\n",
       "209538  078946697X  DK Readers: Creating the X-Men, How It All Beg...   \n",
       "221678  0789466953  DK Readers: Creating the X-Men, How Comic Book...   \n",
       "\n",
       "                bookAuthor yearOfPublication          publisher  \n",
       "209538  Michael Teitelbaum              2000  DK Publishing Inc  \n",
       "221678       James Buckley              2000  DK Publishing Inc  "
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "books.loc[(books.ISBN == '0789466953') | (books.ISBN == '078946697X'),:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "books.loc[books.ISBN == '2070426769','yearOfPublication'] = 2003\n",
    "books.loc[books.ISBN == '2070426769','bookAuthor'] = \"Jean-Marie Gustave Le ClÃ?Â©zio\"\n",
    "books.loc[books.ISBN == '2070426769','publisher'] = \"Gallimard\"\n",
    "books.loc[books.ISBN == '2070426769','bookTitle'] = \"Peuple du ciel, suivi de 'Les Bergers\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "books.yearOfPublication=pd.to_numeric(books.yearOfPublication, errors='coerce')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "books.loc[(books.yearOfPublication > 2006) | (books.yearOfPublication == 0),'yearOfPublication'] = np.NAN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "books.yearOfPublication.fillna(round(books.yearOfPublication.mean()), inplace=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "books.yearOfPublication.isnull().sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "books.loc[(books.ISBN == '193169656X'),'publisher'] = 'other'\n",
    "books.loc[(books.ISBN == '1931696993'),'publisher'] = 'other'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "users.loc[(users.Age > 90) | (users.Age < 5), 'Age'] = np.nan"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "users.Age = users.Age.fillna(users.Age.mean())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "users.Age = users.Age.astype(np.int32)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "ratings_new = ratings[ratings.ISBN.isin(books.ISBN)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "ratings = ratings[ratings.userID.isin(users.userID)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "ratings_explicit = ratings_new[ratings_new.bookRating != 0]\n",
    "ratings_implicit = ratings_new[ratings_new.bookRating == 0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.countplot(data=ratings_explicit , x='bookRating')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(217729, 3)"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "counts1 = ratings_explicit['userID'].value_counts()\n",
    "ratings_explicit = ratings_explicit[ratings_explicit['userID'].isin(counts1[counts1 >= 20].index)]\n",
    "counts = ratings_explicit['bookRating'].value_counts()\n",
    "ratings_explicit = ratings_explicit[ratings_explicit['bookRating'].isin(counts[counts >= 20].index)]\n",
    "ratings_explicit.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(3305, 108380)\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>ISBN</th>\n",
       "      <th>0000913154</th>\n",
       "      <th>0001046438</th>\n",
       "      <th>000104687X</th>\n",
       "      <th>0001047213</th>\n",
       "      <th>0001047973</th>\n",
       "      <th>000104799X</th>\n",
       "      <th>0001048082</th>\n",
       "      <th>0001053736</th>\n",
       "      <th>0001053744</th>\n",
       "      <th>0001055607</th>\n",
       "      <th>...</th>\n",
       "      <th>B0000T6KIM</th>\n",
       "      <th>B0000VZEH8</th>\n",
       "      <th>B0000VZEJQ</th>\n",
       "      <th>B0000X8HIE</th>\n",
       "      <th>B00011SOXI</th>\n",
       "      <th>B00013AX9E</th>\n",
       "      <th>B0001FZGRQ</th>\n",
       "      <th>B0001GMSV2</th>\n",
       "      <th>B0001I1KOG</th>\n",
       "      <th>B000234N3A</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>userID</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>242</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>254</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>507</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>638</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>643</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 108380 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "ISBN    0000913154  0001046438  000104687X  0001047213  0001047973  \\\n",
       "userID                                                               \n",
       "242              0           0           0           0           0   \n",
       "254              0           0           0           0           0   \n",
       "507              0           0           0           0           0   \n",
       "638              0           0           0           0           0   \n",
       "643              0           0           0           0           0   \n",
       "\n",
       "ISBN    000104799X  0001048082  0001053736  0001053744  0001055607  \\\n",
       "userID                                                               \n",
       "242              0           0           0           0           0   \n",
       "254              0           0           0           0           0   \n",
       "507              0           0           0           0           0   \n",
       "638              0           0           0           0           0   \n",
       "643              0           0           0           0           0   \n",
       "\n",
       "ISBN       ...      B0000T6KIM  B0000VZEH8  B0000VZEJQ  B0000X8HIE  \\\n",
       "userID     ...                                                       \n",
       "242        ...               0           0           0           0   \n",
       "254        ...               0           0           0           0   \n",
       "507        ...               0           0           0           0   \n",
       "638        ...               0           0           0           0   \n",
       "643        ...               0           0           0           0   \n",
       "\n",
       "ISBN    B00011SOXI  B00013AX9E  B0001FZGRQ  B0001GMSV2  B0001I1KOG  B000234N3A  \n",
       "userID                                                                          \n",
       "242              0           0           0           0           0           0  \n",
       "254              0           0           0           0           0           0  \n",
       "507              0           0           0           0           0           0  \n",
       "638              0           0           0           0           0           0  \n",
       "643              0           0           0           0           0           0  \n",
       "\n",
       "[5 rows x 108380 columns]"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#Generating ratings matrix from explicit ratings table\n",
    "ratings_matrix = ratings_explicit.pivot(index='userID', columns='ISBN', values='bookRating')\n",
    "userID = ratings_matrix.index\n",
    "ISBN = ratings_matrix.columns\n",
    "ratings_matrix.fillna(0, inplace = True)\n",
    "ratings_matrix = ratings_matrix.astype(np.int32)\n",
    "print(ratings_matrix.shape)\n",
    "ratings_matrix.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "import scipy.sparse as sp\n",
    "\n",
    "def _shuffle(uids, iids, data, random_state):\n",
    "\n",
    "    shuffle_indices = np.arange(len(uids))\n",
    "    random_state.shuffle(shuffle_indices)\n",
    "\n",
    "    return (uids[shuffle_indices],\n",
    "            iids[shuffle_indices],\n",
    "            data[shuffle_indices])\n",
    "\n",
    "def random_train_test_split(interactions_df,\n",
    "                            test_percentage=0.25,\n",
    "                            random_state=None):\n",
    "    \"\"\"\n",
    "    Randomly split interactions between training and testing.\n",
    "\n",
    "    This function takes an interaction set and splits it into\n",
    "    two disjoint sets, a training set and a test set. Note that\n",
    "    no effort is made to make sure that all items and users with\n",
    "    interactions in the test set also have interactions in the\n",
    "    training set; this may lead to a partial cold-start problem\n",
    "    in the test set.\n",
    "\n",
    "    Parameters\n",
    "    ----------\n",
    "\n",
    "    interactions: a scipy sparse matrix containing interactions\n",
    "        The interactions to split.\n",
    "    test_percentage: float, optional\n",
    "        The fraction of interactions to place in the test set.\n",
    "    random_state: np.random.RandomState, optional\n",
    "        The random state used for the shuffle.\n",
    "\n",
    "    Returns\n",
    "    -------\n",
    "\n",
    "    (train, test): (scipy.sparse.COOMatrix,\n",
    "                    scipy.sparse.COOMatrix)\n",
    "         A tuple of (train data, test data)\n",
    "    \"\"\"\n",
    "    interactions = csr_matrix(interactions_df.values)\n",
    "    if random_state is None:\n",
    "        random_state = np.random.RandomState()\n",
    "\n",
    "    interactions = interactions.tocoo()\n",
    "\n",
    "    shape = interactions.shape\n",
    "    uids, iids, data = (interactions.row,\n",
    "                        interactions.col,\n",
    "                        interactions.data)\n",
    "\n",
    "    uids, iids, data = _shuffle(uids, iids, data, random_state)\n",
    "\n",
    "    cutoff = int((1.0 - test_percentage) * len(uids))\n",
    "\n",
    "    train_idx = slice(None, cutoff)\n",
    "    test_idx = slice(cutoff, None)\n",
    "\n",
    "    train = coo_matrix((data[train_idx],\n",
    "                           (uids[train_idx],\n",
    "                            iids[train_idx])),\n",
    "                          shape=shape,\n",
    "                          dtype=interactions.dtype)\n",
    "    test = coo_matrix((data[test_idx],\n",
    "                          (uids[test_idx],\n",
    "                           iids[test_idx])),\n",
    "                         shape=shape,\n",
    "                         dtype=interactions.dtype)\n",
    "\n",
    "    return train, test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "train, test = random_train_test_split(ratings_matrix)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--- Run time:  8.281255984306336 mins ---\n",
      "Train AUC Score: 0.9871253967285156\n",
      "Test AUC Score: 0.6499683856964111\n"
     ]
    }
   ],
   "source": [
    "start_time = time.time()\n",
    "model=LightFM(no_components=115,learning_rate=0.027,loss='warp')\n",
    "model.fit(train,epochs=12,num_threads=4)\n",
    "# with open('saved_model','wb') as f:\n",
    "#     saved_model={'model':model}\n",
    "#     pickle.dump(saved_model, f)\n",
    "auc_train = auc_score(model, train).mean()\n",
    "auc_test = auc_score(model, test).mean()\n",
    "\n",
    "print(\"--- Run time:  {} mins ---\".format((time.time() - start_time)/60))\n",
    "print(\"Train AUC Score: {}\".format(auc_train))\n",
    "print(\"Test AUC Score: {}\".format(auc_test))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "from skopt import forest_minimize\n",
    "\n",
    "def objective(params):\n",
    "    # unpack\n",
    "    epochs, learning_rate, no_components = params\n",
    "\n",
    "    model = LightFM(loss='warp',\n",
    "                    random_state=2016,\n",
    "                    learning_rate=learning_rate,\n",
    "                    no_components=no_components)\n",
    "    model.fit(train, epochs=epochs,\n",
    "              num_threads=4, verbose=True)\n",
    "    \n",
    "    patks = auc_score(model, test,num_threads=4)\n",
    "    maptk = np.mean(patks)\n",
    "    # Make negative because we want to _minimize_ objective\n",
    "    out = -maptk\n",
    "    # Handle some weird numerical shit going on\n",
    "    if np.abs(out + 1) < 0.01 or out < -1.0:\n",
    "        return 0.0\n",
    "    else:\n",
    "        return out"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Iteration No: 1 started. Evaluating function at random point.\n",
      "Epoch 0\n"
     ]
    },
    {
     "ename": "KeyboardInterrupt",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mKeyboardInterrupt\u001b[0m                         Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-31-7a6d34f4a21d>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      6\u001b[0m res_fm = forest_minimize(objective, space, n_calls=20,\n\u001b[0;32m      7\u001b[0m                      \u001b[0mrandom_state\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 8\u001b[1;33m                      verbose=True)\n\u001b[0m\u001b[0;32m      9\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'Maximimum auc found: {:6.5f}'\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m-\u001b[0m\u001b[0mres_fm\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfun\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     10\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'Optimal parameters:'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mC:\\ProgramData\\Anaconda3\\lib\\site-packages\\skopt\\optimizer\\forest.py\u001b[0m in \u001b[0;36mforest_minimize\u001b[1;34m(func, dimensions, base_estimator, n_calls, n_random_starts, acq_func, x0, y0, random_state, verbose, callback, n_points, xi, kappa, n_jobs)\u001b[0m\n\u001b[0;32m    159\u001b[0m                          \u001b[0macq_func\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0macq_func\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    160\u001b[0m                          \u001b[0mxi\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mxi\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mkappa\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mkappa\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mverbose\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mverbose\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 161\u001b[1;33m                          callback=callback, acq_optimizer=\"sampling\")\n\u001b[0m",
      "\u001b[1;32mC:\\ProgramData\\Anaconda3\\lib\\site-packages\\skopt\\optimizer\\base.py\u001b[0m in \u001b[0;36mbase_minimize\u001b[1;34m(func, dimensions, base_estimator, n_calls, n_random_starts, acq_func, acq_optimizer, x0, y0, random_state, verbose, callback, n_points, n_restarts_optimizer, xi, kappa, n_jobs)\u001b[0m\n\u001b[0;32m    246\u001b[0m     \u001b[1;32mfor\u001b[0m \u001b[0mn\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mn_calls\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    247\u001b[0m         \u001b[0mnext_x\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0moptimizer\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mask\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 248\u001b[1;33m         \u001b[0mnext_y\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mfunc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnext_x\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    249\u001b[0m         \u001b[0mresult\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0moptimizer\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtell\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnext_x\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mnext_y\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    250\u001b[0m         \u001b[0mresult\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mspecs\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mspecs\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m<ipython-input-30-854adedd1b7b>\u001b[0m in \u001b[0;36mobjective\u001b[1;34m(params)\u001b[0m\n\u001b[0;32m     10\u001b[0m                     no_components=no_components)\n\u001b[0;32m     11\u001b[0m     model.fit(train, epochs=epochs,\n\u001b[1;32m---> 12\u001b[1;33m               num_threads=4, verbose=True)\n\u001b[0m\u001b[0;32m     13\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     14\u001b[0m     \u001b[0mpatks\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mauc_score\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmodel\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtest\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mnum_threads\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m4\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mC:\\ProgramData\\Anaconda3\\lib\\site-packages\\lightfm\\lightfm.py\u001b[0m in \u001b[0;36mfit\u001b[1;34m(self, interactions, user_features, item_features, sample_weight, epochs, num_threads, verbose)\u001b[0m\n\u001b[0;32m    477\u001b[0m                                 \u001b[0mepochs\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mepochs\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    478\u001b[0m                                 \u001b[0mnum_threads\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mnum_threads\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 479\u001b[1;33m                                 verbose=verbose)\n\u001b[0m\u001b[0;32m    480\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    481\u001b[0m     def fit_partial(self, interactions,\n",
      "\u001b[1;32mC:\\ProgramData\\Anaconda3\\lib\\site-packages\\lightfm\\lightfm.py\u001b[0m in \u001b[0;36mfit_partial\u001b[1;34m(self, interactions, user_features, item_features, sample_weight, epochs, num_threads, verbose)\u001b[0m\n\u001b[0;32m    574\u001b[0m                             \u001b[0msample_weight_data\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    575\u001b[0m                             \u001b[0mnum_threads\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 576\u001b[1;33m                             self.loss)\n\u001b[0m\u001b[0;32m    577\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    578\u001b[0m             \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_check_finite\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mC:\\ProgramData\\Anaconda3\\lib\\site-packages\\lightfm\\lightfm.py\u001b[0m in \u001b[0;36m_run_epoch\u001b[1;34m(self, item_features, user_features, interactions, sample_weight, num_threads, loss)\u001b[0m\n\u001b[0;32m    613\u001b[0m                      \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0muser_alpha\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    614\u001b[0m                      \u001b[0mnum_threads\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 615\u001b[1;33m                      self.random_state)\n\u001b[0m\u001b[0;32m    616\u001b[0m         \u001b[1;32melif\u001b[0m \u001b[0mloss\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;34m'bpr'\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    617\u001b[0m             fit_bpr(CSRMatrix(item_features),\n",
      "\u001b[1;31mKeyboardInterrupt\u001b[0m: "
     ]
    }
   ],
   "source": [
    "space = [(1, 40), # epochs\n",
    "         (10**-4, 0.5, 'log-uniform'), # learning_rate\n",
    "         (20, 200), # no_components\n",
    "        ]\n",
    "\n",
    "res_fm = forest_minimize(objective, space, n_calls=20,\n",
    "                     random_state=0,\n",
    "                     verbose=True)\n",
    "print('Maximimum auc found: {:6.5f}'.format(-res_fm.fun))\n",
    "print('Optimal parameters:')\n",
    "params = ['epochs', 'learning_rate', 'no_components']\n",
    "for (p, x_) in zip(params, res_fm.x):\n",
    "    print('{}: {}'.format(p, x_))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
